package com.leyou.common.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: HuYi.Zhang
 * @create: 2018-04-25 09:13
 **/
public class NumberUtils {

    public static boolean isInt(Double num) {
        return num.intValue() == num;
    }

    /**
     * 判断字符串是否是数值格式
     * @param str
     * @return
     */
    public static boolean isDigit(String str){
        if(str == null || str.trim().equals("")){
            return false;
        }
        return str.matches("^\\d+$");
    }

    /**
     * 将一个小数精确到指定位数
     * @param num
     * @param scale
     * @return
     */
    public static double scale(double num, int scale) {
        BigDecimal bd = new BigDecimal(num);
        return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    // 从字符串中根据正则表达式寻找，返回找到的数字数组
    public static Double[] searchNumber(String value, String regex){
        List<Double> doubles = new ArrayList<>();
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(value);
        if(matcher.find()) {
            MatchResult result = matcher.toMatchResult();
            for (int i = 1; i <= result.groupCount(); i++) {
                doubles.add(Double.valueOf(result.group(i)));
            }
        }
        return doubles.toArray(new Double[doubles.size()]);
    }

    /**
     * 生成指定位数的随机数字
     * @param len
     * @return
     */
    public static String generateCode(int len){
        len = Math.min(len, 8);
        int min = Double.valueOf(Math.pow(10, len - 1)).intValue();
        int num = new Random().nextInt(Double.valueOf(Math.pow(10, len + 1)).intValue() - 1) + min;
        return String.valueOf(num).substring(0,len);
    }

/*
————————————————
        版权声明：本文为CSDN博主「zcylxzyh」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
        原文链接：https://blog.csdn.net/zcylxzyh/article/details/97616746*/


/**由于底层对该函数支持不好，自己写了一个 added by shixianjun
  * 对于比较大的数 也没有问题 可以对科学计数法形式的数进行处理
  * @param str
  * @return 无效串返回0.0
 * 这个是我自己网上找的 --莫京
  */
 public static double toDouble(String str) {
  
       //re小数点之前的数,re1小数点之后的数,re2 E之后的数
        double re=0.0,re1=0.0;
        int re2=0;
        double index=1.0;
        boolean flag=true;//正负标志 true 正 false负
        boolean eflag=true;//e之后的指数正负 true正 false 负
        if(str==null) {
        return 0.0;
        }
        
        byte point=0;//在小数点之前0，之后1
        byte ebefore=0;//在E之前0，之后1
        
        int leng=str.length();
        if(leng<=0) {
        return 0.0;
        }
        char temp[];//串临时保存在temp数组
        
        //判断是整数还是负数，对flag进行赋值，并去掉（+ -）符号
        if(str.startsWith("+")) {
        temp=str.substring(1).toCharArray();
        leng--;
        }else if(str.startsWith("-")) {
        flag=false;
        temp=str.substring(1).toCharArray();
        leng--;
        }else{
        temp=str.toCharArray();
        };
        
        
        /**检查每位数把小数点之前的保存在re中，小数点之后的
  * 的保存在re1中，e之后的保存在re2中
 */
        for(int i=0;i<leng;i++) {
        
        if(temp[i]>='0' && temp[i]<='9') {
        if(ebefore==0) {
        if(point==0) {
        re=re*10.0+(temp[i]-48);
        }else if(point==1) {
        index=index*0.1;
        re1=re1+(temp[i]-48)*index;
        }
        }else if(ebefore==1) {
        re2=re2*10+(temp[i]-48);
        }
        
        
        
        }else if(temp[i]=='.') {
        
        point++;
        if(point>1) {//两个点为无效
        return 0.0;
        }
        }else if(temp[i]=='e' ||temp[i]=='E') {
        
        ebefore++;
        if(ebefore>1) {//两个E为无效
        return 0.0;
        }
        }else if(temp[i]=='+' || temp[i]=='-'){
        if(ebefore==1 && temp[i]=='-') {
        eflag=false;
        }else {//E之前出现了 + -号
        return 0.0;
        }
        }else {
        return 0.0;
        }
        
        }//end for
        
        if(eflag==false) {
        re2=re2*(-1);
        }
//info("out stringTOdouble==re=eee14="+Math.pow(10,-14));
        if(flag==false) {
        return (re+re1)*Math.pow(10,re2*1.0)*(-1.0);
        }else {
        return (re+re1)*Math.pow(10,re2*1.0);
        }

        }
//        ————————————————
//        版权声明：本文为CSDN博主「holemole」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
//        原文链接：https://blog.csdn.net/holemole/article/details/4220183
}